
local SkUtil = require 'packages/jilvRem/utility/_base'

local U = require "packages/utility/utility"

--- 执行极略三国固定的随机效果池
---@param player ServerPlayer @ 来源角色
---@param p ServerPlayer @ 执行效果的角色
---@param info integer @ 执行的效果序号
---@param skill_name string @ 技能名
SkUtil.DoTiangongEffect = function (player, p, info, skill_name)
  local room = p.room
  switch(info, {
    [1] = function ()
      p:turnOver()
    end,
    [2] = function ()
      local judge = {
        who = p,
        reason = "lightning",
        pattern = ".|2~9|spade",
      }
      room:judge(judge)
      if p.dead then return end
      if judge.card.suit == Card.Spade and judge.card.number > 1 and judge.card.number < 10 then
        room:damage{
          to = p,
          damage = 3,
          damageType = fk.ThunderDamage,
          skillName = "lightning_skill",
        }
      end
    end,
    [3] = function ()
      room:addPlayerMark(p, MarkEnum.AddMaxCards, 1)
    end,
    [4] = function ()
      room:addPlayerMark(player, MarkEnum.SlashResidue, 1)
    end,
    [5] = function ()
      local skills = table.map(table.filter(p.player_skills, function(s)
        return s:isPlayerSkill(p) and s.visible
      end), function(s)
        return s.name
      end)
      if #skills > 0 then
        room:handleAddLoseSkills(p, "-"..table.random(skills), nil, true, false)
      end
    end,
    [6] = function ()
      local skills = {}
      for _, general in ipairs(room.general_pile) do
        local g = Fk.generals[general]
        if g.kingdom == "wei" then
          table.insertTableIfNeed(skills, g:getSkillNameList())
        end
      end
      skills = table.filter(skills, function(s)
        return not p:hasSkill(s, true)
      end)
      if #skills > 0 then
        room:handleAddLoseSkills(p, table.random(skills), nil, true, false)
      end
    end,
    [7] = function ()
      local skills = {}
      for _, general in ipairs(room.general_pile) do
        local g = Fk.generals[general]
        if g.kingdom == "shu" then
          table.insertTableIfNeed(skills, g:getSkillNameList())
        end
      end
      skills = table.filter(skills, function(s)
        return not p:hasSkill(s, true)
      end)
      if #skills > 0 then
        room:handleAddLoseSkills(p, table.random(skills), nil, true, false)
      end
    end,
    [8] = function ()
      local skills = {}
      for _, general in ipairs(room.general_pile) do
        local g = Fk.generals[general]
        if g.kingdom == "wu" then
          table.insertTableIfNeed(skills, g:getSkillNameList())
        end
      end
      skills = table.filter(skills, function(s)
        return not p:hasSkill(s, true)
      end)
      if #skills > 0 then
        room:handleAddLoseSkills(p, table.random(skills), nil, true, false)
      end
    end,
    [9] = function ()
      local skills = {}
      for _, general in ipairs(room.general_pile) do
        local g = Fk.generals[general]
        if g.kingdom == "qun" then
          table.insertTableIfNeed(skills, g:getSkillNameList())
        end
      end
      skills = table.filter(skills, function(s)
        return not p:hasSkill(s, true)
      end)
      if #skills > 0 then
        room:handleAddLoseSkills(p, table.random(skills), nil, true, false)
      end
    end,
    [10] = function ()
      local skills = {}
      for _, general in ipairs(room.general_pile) do
        local g = Fk.generals[general]
        if not table.contains({"wei", "shu", "wu", "qun"}, g.kingdom) then
          table.insertTableIfNeed(skills, g:getSkillNameList())
        end
      end
      skills = table.filter(skills, function(s)
        return not p:hasSkill(s, true)
      end)
      if #skills > 0 then
        room:handleAddLoseSkills(p, table.random(skills), nil, true, false)
      end
    end,
    [11] = function ()
      local card = Fk:cloneCard("savage_assault")
      card.skillName = skill_name,
      room:useCard{
        from = p.id,
        card = card,
      }
    end,
    [12] = function ()
      local card = Fk:cloneCard("archery_attack")
      card.skillName = skill_name,
      room:useCard{
        from = p.id,
        card = card,
      }
    end,
    [13] = function ()
      local card = Fk:cloneCard("god_salvation")
      card.skillName = skill_name,
      room:useCard{
        from = p.id,
        card = card,
      }
    end,
    [14] = function ()
      local card = Fk:cloneCard("amazing_grace")
      card.skillName = skill_name,
      room:useCard{
        from = p.id,
        card = card,
      }
    end,
    [15] = function ()
      local card = Fk:cloneCard("ex_nihilo")
      card.skillName = skill_name,
      room:useCard{
        from = p.id,
        card = card,
      }
    end,
    [16] = function ()
      local card = Fk:cloneCard("peach")
      card.skillName = skill_name,
      room:useCard{
        from = p.id,
        card = card,
      }
    end,
    [17] = function ()
      room:useVirtualCard("slash", nil, p, room:getOtherPlayers(p), skill_name, true)
    end,
    [18] = function ()
      room:useVirtualCard("thunder__slash", nil, p, room:getOtherPlayers(p), skill_name, true)
    end,
    [19] = function ()
      room:useVirtualCard("fire__slash", nil, p, room:getOtherPlayers(p), skill_name, true)
    end,
    [20] = function ()
      room:useVirtualCard("duel", nil, p, room:getOtherPlayers(p), skill_name, true)
    end,
    [21] = function ()
      local cards = room:getCardsFromPileByRule(".|.|heart,diamond", 2, "allPiles")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, p, fk.ReasonJustMove, skill_name, nil, true, player.id)
      end
    end,
    [22] = function ()
      local cards = room:getCardsFromPileByRule(".|.|spade,club", 2, "allPiles")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, p, fk.ReasonJustMove, skill_name, nil, true, player.id)
      end
    end,
    [23] = function ()
      local cards = room:getCardsFromPileByRule(".|.|.|.|.|basic", 2, "allPiles")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, p, fk.ReasonJustMove, skill_name, nil, true, player.id)
      end
    end,
    [24] = function ()
      local cards = room:getCardsFromPileByRule(".|.|.|.|.|trick", 2, "allPiles")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, p, fk.ReasonJustMove, skill_name, nil, true, player.id)
      end
    end,
    [25] = function ()
      local cards = room:getCardsFromPileByRule(".|.|.|.|.|equip", 2, "allPiles")
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, p, fk.ReasonJustMove, skill_name, nil, true, player.id)
      end
    end,
    [26] = function ()
      room:damage({
        from = player,
        to = p,
        damage = 1,
        skillName = skill_name,
      })
    end,
    [27] = function ()
      room:damage({
        from = player,
        to = p,
        damage = 1,
        damageType = fk.ThunderDamage,
        skillName = skill_name,
      })
    end,
    [28] = function ()
      room:damage({
        from = player,
        to = p,
        damage = 1,
        damageType = fk.FireDamage,
        skillName = skill_name,
      })
    end,
    [29] = function ()
      for _, q in ipairs(room:getOtherPlayers(p)) do
        if not q.dead then
          room:damage({
            from = p,
            to = q,
            damage = 1,
            skillName = skill_name,
          })
        end
      end
    end,
    [30] = function ()
      room:changeMaxHp(p, 1)
    end,
    [31] = function ()
      room:changeMaxHp(p, -1)
    end,
    [32] = function ()
      if p:isWounded() then
        room:recover({
          from = player,
          who = p,
          num = 1,
          recoverBy = player,
          skillName = skill_name,
        })
      end
    end,
    [33] = function ()
      if p:isWounded() then
        room:recover({
          from = player,
          who = p,
          num = math.min(2, p:getLostHp()),
          recoverBy = player,
          skillName = skill_name,
        })
      end
    end,
    [34] = function ()
      room:loseHp(p, 1, skill_name)
    end,
    [35] = function ()
      room:loseHp(p, 2, skill_name)
    end,
    [36] = function ()
      room:loseHp(p, 1, skill_name)
      if not p.dead then
        p:drawCards(5, skill_name)
      end
    end,
    [37] = function ()
      p:drawCards(2, skill_name)
    end,
    [38] = function ()
      p:drawCards(3, skill_name)
    end,
    [39] = function ()
      p:drawCards(4, skill_name)
    end,
    [40] = function ()
      if not p:isNude() then
        local cards = table.random(p:getCardIds("he"), 2)
        room:throwCard(cards, skill_name, p, p)
      end
    end,
    [41] = function ()
      if not p:isNude() then
        local cards = table.random(p:getCardIds("he"), 3)
        room:throwCard(cards, skill_name, p, p)
      end
    end,
    [42] = function ()
      if not p:isNude() then
        local cards = table.random(p:getCardIds("he"), 4)
        room:throwCard(cards, skill_name, p, p)
      end
    end,
    [43] = function ()
      if not p:isNude() then
        local num = #p:getCardIds("he")
        p:throwAllCards("he")
        if not p.dead then
          p:drawCards(num, skill_name)
        end
      end
    end,
    [44] = function ()
      local cards = {}
      for _, q in ipairs(room:getOtherPlayers(p)) do
        if not q:isNude() then
          table.insert(cards, table.random(q:getCardIds("he")))
        end
      end
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, p, fk.ReasonPrey, skill_name, nil, false, p.id)
      end
    end,
    [45] = function ()
      local tos = table.filter(room:getOtherPlayers(p), function(q)
        return q:getHandcardNum() > p:getHandcardNum()
      end)
      if #tos > 0 then
        U.swapHandCards(room, p, p, table.random(tos), skill_name)
      end
    end,
    [46] = function ()
      local tos = table.filter(room:getOtherPlayers(p), function(q)
        return q:getHandcardNum() < p:getHandcardNum()
      end)
      if #tos > 0 then
        U.swapHandCards(room, p, p, table.random(tos), skill_name)
      end
    end,
  })
end

return SkUtil
